package org.teremail.message.builder;

import java.util.ArrayList;
import java.util.List;

import org.teremail.message.Content;
import org.teremail.message.ContentHeaders;
import org.teremail.message.Entity;
import org.teremail.message.MultipartEntity;

/**
 * Utility class to help construct a multipart entity, i.e. a list of child
 * parts.
 * 
 * @author Michael Barker
 *
 */
public class MultipartEntityBuilder implements MultipartBuilder {

    private final MultipartEntity originalEntity;
    private final List<EntityBuilder> partBuilders;
    private final ContentHeadersBuilder contentHeadersBuilder;
    private boolean hasChanged = false;
    private String preamble;
    private String epilogue;
    private String id;

    public MultipartEntityBuilder(MultipartEntity originalEntity, 
            ContentHeadersBuilder contentHeadersBuilder,
            List<EntityBuilder> partBuilders) {
        this.originalEntity = originalEntity;
        this.contentHeadersBuilder = contentHeadersBuilder;
        this.partBuilders = partBuilders;
    }
    
    public MultipartEntityBuilder(ContentHeadersBuilder contentHeadersBuilder,
            List<EntityBuilder> partBuilders) {
        this(null, contentHeadersBuilder, partBuilders);
    }
    
    public MultipartEntityBuilder(ContentHeadersBuilder contentHeadersBuilder) {
        this(contentHeadersBuilder, new ArrayList<EntityBuilder>());
    }
    
    public MultipartEntityBuilder(MultipartEntity multipartEntity,
            List<EntityBuilder> partBuilders) {
        this(multipartEntity, 
                new ContentHeadersBuilder(multipartEntity.getContentHeader()),
                partBuilders);
    }

    public MultipartEntityBuilder() {
        this(null, new ContentHeadersBuilder(), new ArrayList<EntityBuilder>());
    }

    public SimpleEntityBuilder addSimpleEntity(Content c) {
        hasChanged = true;
        SimpleEntityBuilder seb = new SimpleEntityBuilder();
        seb.setContent(c);
        partBuilders.add(seb);
        return seb;
    }
    
    public MultipartEntityBuilder setPreamble(String preamble) {
        this.preamble = preamble;
        return this;
    }

    public MultipartEntityBuilder setEpilogue(String epilogue) {
        this.epilogue = epilogue;
        return this;
    }
    
    public boolean hasChanged() {
        return hasChanged || originalEntity == null || childPartChanged();
    }
    
    private boolean childPartChanged() {
        for (EntityBuilder eb : partBuilders) {
            if (eb.hasChanged()) {
                return true;
            }
        }
        return false;
    }
    
    public MultipartEntity build() {
        if (hasChanged()) {
            List<Entity> parts = new ArrayList<Entity>();
            for (EntityBuilder eb : partBuilders) {
                parts.add(eb.build());
            }
            ContentHeaders ch = contentHeadersBuilder.build();
            return new MultipartEntity(id, ch, preamble, parts, epilogue);
        } else {
            return originalEntity;
        }
    }

    public MultipartEntityBuilder setId(String id) {
        this.id = id;
        hasChanged = true;
        return this;
    }
    
    public String getId() {
        return id;
    }    

    public MultipartEntityBuilder clearParts() {
        partBuilders.clear();
        hasChanged = true;
        return this;
    }

    public MultipartEntityBuilder addEntityBuilder(EntityBuilder entityBuilder) {
        partBuilders.add(entityBuilder);
        hasChanged = true;
        return this;
    }

    public boolean isMultipart() {
        return true;
    }

    public void setContentHeaders(String contentHeaders) {
        contentHeadersBuilder.load(contentHeaders);
    }

}
